package com.cn.bulu.utils.ClothCurtain;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.cn.bulu.pojo.Composition;

public class Calculate {

	/**
	 * 2舍3入的方法
	 * @param math
	 * @return
	 */
	public static Integer FUNC(Double math) {
		String BuFuString = math.toString();
		int a = BuFuString.indexOf(".");
		Integer BuFuNumber = Integer.parseInt(BuFuString.substring(0, a));
		if (Integer.parseInt(BuFuString.substring(a + 1, a + 2)) >= 3) {
			BuFuNumber += 1;
		}
		return BuFuNumber;
	}

	
	
	/**
	 * 不拼接 幅宽 倍折 花距 折边 倒幅1可以 0不可以 宽输入 高输入
	 * @param breadth
	 * @param times_fold
	 * @param spur
	 * @param hem
	 * @param inverte
	 * @param wide
	 * @param high
	 * @param breadthStatus
	 * @return
	 */
	public static Map<String, Object> FixedNPin(Double breadth, Double times_fold, Double spur, Double hem,
		Integer inverte, Double wide, Double high, Integer breadthStatus) {
		Map<String, Object> map = new HashMap<String, Object>();
		// 主布用布量
		Double clothNumber = 0.0;
		if (breadthStatus == 0) {// 输入的是定高
			// Double times_foldD = times_fold.doubleValue();
			if (breadth >= high) {
				// 计算主布用量(宽)
				clothNumber = wide * times_fold + spur;
				// 用量
				map.put("clothNumber", clothNumber);
				// 用布数（多少幅）
				map.put("dosage", 1);
				// 实际宽
				map.put("actualWide", clothNumber);
				// 实际高
				map.put("actualHigh", high);
				// 使用宽
				map.put("useWide", clothNumber);
				// 使用高
				map.put("useHigh", breadth);
				// 是否倒幅制作 1倒幅 0不倒幅
				map.put("useInverte", 0);
			}else {
				if (inverte == 1) {// 能倒幅
					// 计算主布用量
					Double BuFuNumberD = wide * times_fold / breadth;
					Integer BuFuNumber = Calculate.FUNC(BuFuNumberD);
					clothNumber = high * BuFuNumber + spur * (Arith.sub(BuFuNumber, 1)) + hem * BuFuNumber;
					if (BuFuNumber <= 2) {
						// 用量
						map.put("clothNumber", clothNumber);
						// 用量(布幅数)
						map.put("dosage", BuFuNumber);
						// 实际宽
						map.put("actualWide", wide);
						// 实际高
						map.put("actualHigh", clothNumber);
						// 使用宽
						map.put("useWide", BuFuNumber * breadth);
						// 使用高
						map.put("useHigh", clothNumber);
						// 是否倒幅制作 1倒幅 0不倒幅
						map.put("useInverte", 1);
					} else {
						// 用量
						map.put("clothNumber", clothNumber);
						// 用量(布幅数)
						map.put("dosage", BuFuNumber);
						// 实际宽
						map.put("actualWide", BuFuNumber * breadth);
						// 实际高
						map.put("actualHigh", clothNumber);
						// 使用宽
						map.put("useWide", BuFuNumber * breadth);
						// 使用高
						map.put("useHigh", clothNumber);
						// 是否倒幅制作 1倒幅 0不倒幅
						map.put("useInverte", 1);
					}
				} else {// 不可以倒幅
					System.err.println("这个不能调！！！原因是composition表中的inverte字段为0");
					// 暂时不存在，无法计算
				}
			}
		} else {// 输入的是定宽
			if (inverte == 1) {
				if (breadth >= (Arith.add(high, hem))) {
					// 倒幅制作的用布量
					Double clothNumber1 = Arith.add(wide * times_fold, spur);
					// 不倒幅制作的用布量
					Double BuFuNumberD = wide * times_fold / breadth;// (3舍4入)
					Integer BuFuNumber = Calculate.FUNC(BuFuNumberD);
					Double clothNumber2 = Arith.add(high * BuFuNumber + spur * (Arith.sub(BuFuNumber, 1)),
							hem * BuFuNumber);
					if (clothNumber1 >= clothNumber2) {
						// 倒幅进行制作用布量少
						map.put("clothNumber", clothNumber2);
						// 用布数（多少幅）
						map.put("dosage", 1);
						// 实际宽
						map.put("actualWide", clothNumber2);
						// 实际高
						map.put("actualHigh", Arith.sub(breadth, high));
						// 使用宽
						map.put("useWide", clothNumber2);
						// 使用高
						map.put("useHigh", breadth);
						// 是否倒幅制作 1倒幅 0不倒幅
						map.put("useInverte", 1);
					} else {
						// 不倒幅进行制作用布量少
						map.put("clothNumber", clothNumber1);
						if (BuFuNumber <= 2) {
							// 用量(布幅数)
							map.put("dosage", BuFuNumber);
							// 实际宽
							map.put("actualWide", wide);
							// 实际高
							map.put("actualHigh", clothNumber1);
							// 使用宽
							map.put("useWide", BuFuNumber * breadth);
							// 使用高
							map.put("useHigh", clothNumber1);
							// 是否倒幅制作 1倒幅 0不倒幅
							map.put("useInverte", 0);
						} else {
							// 用量(布幅数)
							map.put("dosage", BuFuNumber);
							// 实际宽
							map.put("actualWide", BuFuNumber * breadth);
							// 实际高
							map.put("actualHigh", clothNumber1);
							// 使用宽
							map.put("useWide", BuFuNumber * breadth);
							// 使用高
							map.put("useHigh", clothNumber1);
							// 是否倒幅制作 1倒幅 0不倒幅
							map.put("useInverte", 0);
						}
					}
				} else {
					// 计算主布用布量
					// 布幅数
					Double BuFuNumberD = wide * times_fold / breadth;// (3舍4入)
					Integer BuFuNumber = Calculate.FUNC(BuFuNumberD);
					clothNumber = high * BuFuNumber + spur * (Arith.sub(BuFuNumber, 1)) + hem * BuFuNumber;
					// 用量
					map.put("clothNumber", clothNumber);
					if (BuFuNumber <= 2) {
						// 用量(布幅数)
						map.put("dosage", BuFuNumber);
						// 实际宽
						map.put("actualWide", wide);
						// 实际高
						map.put("actualHigh", clothNumber);
						// 使用宽
						map.put("useWide", BuFuNumber * breadth);
						// 使用高
						map.put("useHigh", clothNumber);
						// 是否倒幅制作 1倒幅 0不倒幅
						map.put("useInverte", 0);
					} else {
						// 用量(布幅数)
						map.put("dosage", BuFuNumber);
						// 实际宽
						map.put("actualWide", BuFuNumber * breadth);
						// 实际高
						map.put("actualHigh", clothNumber);
						// 使用宽
						map.put("useWide", BuFuNumber * breadth);
						// 使用高
						map.put("useHigh", clothNumber);
						// 是否倒幅制作 1倒幅 0不倒幅
						map.put("useInverte", 0);
					}
				}
			} else {
				// 计算主布用布量
				// 布幅数
				Double BuFuNumberD = wide * times_fold / breadth;// (3舍4入)
				Integer BuFuNumber = Calculate.FUNC(BuFuNumberD);
				clothNumber = high * BuFuNumber + spur * (Arith.sub(BuFuNumber, 1)) + hem * BuFuNumber;
				// 用量
				map.put("clothNumber", clothNumber);
				if (BuFuNumber <= 2) {
					// 用量(布幅数)
					map.put("dosage", BuFuNumber);
					// 实际宽
					map.put("actualWide", wide);
					// 实际高
					map.put("actualHigh", clothNumber);
					// 使用宽
					map.put("useWide", BuFuNumber * breadth);
					// 使用高
					map.put("useHigh", clothNumber);
					// 是否倒幅制作 1倒幅 0不倒幅
					map.put("useInverte", 0);
				} else {
					// 用量(布幅数)
					map.put("dosage", BuFuNumber);
					// 实际宽
					map.put("actualWide", BuFuNumber * breadth);
					// 实际高
					map.put("actualHigh", clothNumber);
					// 使用宽
					map.put("useWide", BuFuNumber * breadth);
					// 使用高
					map.put("useHigh", clothNumber);
					// 是否倒幅制作 1倒幅 0不倒幅
					map.put("useInverte", 0);
				}
			}
		}
		return map;
	}
	
	
	
	
	/**
	 * 计算拼接
	 * @param times_fold
	 *            倍折
	 * @param hem
	 *            折边
	 * @param wide
	 *            宽
	 * @param high
	 *            高
	 * @param production
	 *            制作方法 几开
	 * @param list
	 *            样品的构成集合
	 * @return
	 */
	public static Map<String, Object> FixedWidePin(Double times_fold, Double hem, Double wide, Double high,
			Integer production, List<Composition> list) {
		List<Composition> zhubu = new ArrayList<>();
		List<Composition> peibu = new ArrayList<>();
		List<Composition> sha = new ArrayList<>();
		Map<String, Object> map = new HashMap<>();
		for (int a = 0; a < list.size(); a++) {
			switch (list.get(a).getType()) {
			// 主布
			case 1:
				zhubu.add(list.get(a));
				break;
			// 配布
			case 2:
				peibu.add(list.get(a));
				break;
			// 纱
			case 3:
				sha.add(list.get(a));
				break;
			// 帘头
			default:
				break;
			}
		}
		// 一个主布 没有主布拼接
		if (zhubu.size() == 1) {
			// 主布定高
			if (zhubu.get(0).getBreadthStatus() == 0) {
				map = Calculate.FixedNPin(zhubu.get(0).getBreadth(), times_fold, zhubu.get(0).getSpur(), hem,
						zhubu.get(0).getInverte(), wide, high, zhubu.get(0).getBreadthStatus());
				if(map==null)  return map;
				map.put("serialnumber", zhubu.get(0).getSerialnumber());
				List<Map<String, Object>> peibuList = new ArrayList<>();
				// 没有倒幅用
				if ((Integer) map.get("useInverte") == 0) {
					for (int x = 0; x < peibu.size(); x++) {
						// 配布是横拼
						if (peibu.get(x).getPutTogether() == 1) {
							Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
									zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(),
									(Double) map.get("actualWide") / production,
									peibu.get(x).getPutNumber() * production, peibu.get(x).getBreadthStatus());
							peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
							peibuList.add(peibuMap);
						} else {// 配布是竖拼
							Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
									zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(), peibu.get(x).getPutNumber(),
									(Double) map.get("actualHigh"), peibu.get(x).getBreadthStatus());

							map.put("clothNumber",
									Arith.sub((Double) map.get("clothNumber"), peibu.get(x).getPutNumber()));
							map.put("useWide", Arith.sub((Double) map.get("useWide"), peibu.get(x).getPutNumber()));
							map.put("actualWide",
									Arith.sub((Double) map.get("actualWide"), peibu.get(x).getPutNumber()));
							peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
							peibuList.add(peibuMap);
						}
					}
					map.put("peibuList", peibuList);
				} else {// 倒幅 当成定宽用
					for (int x = 0; x < peibu.size(); x++) {
						// 配布是横拼
						if (peibu.get(x).getPutTogether() == 1) {
							boolean shupin = false;
							Double sumShupin = 0.0;
							for (int y = 0; y < peibu.size(); y++) {
								if (peibu.get(y).getPutTogether() == 2) {
									sumShupin = Arith.add(sumShupin, peibu.get(y).getPutNumber());
									shupin = true;
								}
							}
							// 还有竖拼的配布
							if (shupin) {// 这个地方计算的配布宽度就是遮光里布的宽度 高度为输入高
								Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
										zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(),
										Arith.add((Double) map.get("actualWide"), sumShupin) / production,
										peibu.get(x).getPutNumber() * production, peibu.get(x).getBreadthStatus());
								peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
								peibuList.add(peibuMap);
							} else {
								Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
										zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(),
										(Double) map.get("actualWide") / production,
										peibu.get(x).getPutNumber() * production, peibu.get(x).getBreadthStatus());
								peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
								peibuList.add(peibuMap);
							}
						} else {// 配布是竖拼
							Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
									zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(), peibu.get(x).getPutNumber(),
									(Double) map.get("actualHigh"), peibu.get(x).getBreadthStatus());
							peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
							peibuList.add(peibuMap);
						}
					}
					map.put("peibuList", peibuList);
				}
			} else {// 主布定宽
				map = Calculate.FixedNPin(zhubu.get(0).getBreadth(), times_fold, zhubu.get(0).getSpur(), hem,
						zhubu.get(0).getInverte(), wide, high, zhubu.get(0).getBreadthStatus());
				List<Map<String, Object>> peibuList = new ArrayList<>();
				// 没有倒幅用
				if ((Integer) map.get("useInverte") == 0) {
					for (int x = 0; x < peibu.size(); x++) {
						// 配布是横拼
						if (peibu.get(x).getPutTogether() == 1) {
							boolean shupin = false;
							Double sumShupin = 0.0;
							for (int y = 0; y < peibu.size(); y++) {
								if (peibu.get(y).getPutTogether() == 2) {
									sumShupin = Arith.add(sumShupin, peibu.get(y).getPutNumber());
									shupin = true;
								}
							}
							// 还有竖拼的配布
							if (shupin) {// 这个地方计算的配布宽度就是遮光里布的宽度 高度为输入高
								Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
										zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(),
										Arith.add((Double) map.get("actualWide"), sumShupin) / production,
										peibu.get(x).getPutNumber() * production, peibu.get(x).getBreadthStatus());
								peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
								peibuList.add(peibuMap);
							} else {
								Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
										zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(),
										(Double) map.get("actualWide") / production,
										peibu.get(x).getPutNumber() * production, peibu.get(0).getBreadthStatus());
								peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
								peibuList.add(peibuMap);
							}
						} else {// 配布是竖拼
							Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
									zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(), peibu.get(x).getPutNumber(),
									(Double) map.get("actualHigh"), peibu.get(0).getBreadthStatus());
							peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
							peibuList.add(peibuMap);
						}
					}
					map.put("peibuList", peibuList);
				} else {// 倒幅 当成定高用
					for (int x = 0; x < peibu.size(); x++) {
						// 配布是横拼
						if (peibu.get(x).getPutTogether() == 1) {
							Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
									zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(),
									(Double) map.get("actualWide") / production,
									peibu.get(x).getPutNumber() * production, peibu.get(x).getBreadthStatus());
							peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
							peibuList.add(peibuMap);
						} else {// 配布是竖拼
							Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
									zhubu.get(0).getSpur(), 0.0, zhubu.get(0).getInverte(), peibu.get(x).getPutNumber(),
									(Double) map.get("actualHigh"), peibu.get(x).getBreadthStatus());
							map.put("clothNumber",
									Arith.sub((Double) map.get("clothNumber"), peibu.get(x).getPutNumber()));
							map.put("useWide", Arith.sub((Double) map.get("useWide"), peibu.get(x).getPutNumber()));
							map.put("actualWide",
									Arith.sub((Double) map.get("actualWide"), peibu.get(x).getPutNumber()));
							peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
							peibuList.add(peibuMap);
						}
					}
					map.put("peibuList", peibuList);
				}
			}
		} else {// 多种主布拼接
			List<Map<String, Object>> zhubuList = new ArrayList<>();
			for (int x = 0; x < zhubu.size(); x++) {
				// 判断是否是横拼的主布 是
				if (zhubu.get(x).getPutTogether() == 1) {
					Map<String, Object> zhubuMap = Calculate.FixedNPin(zhubu.get(x).getBreadth(), times_fold,
							zhubu.get(0).getSpur(), hem, zhubu.get(0).getInverte(), wide,
							Arith.add(high, hem) * zhubu.get(x).getPutNumber(), zhubu.get(x).getBreadthStatus());
					zhubuMap.put("putNumber", zhubu.get(x).getPutNumber());
					zhubuMap.put("putTogether", zhubu.get(x).getPutTogether());
					zhubuMap.put("serialnumber", zhubu.get(x).getSerialnumber());
					zhubuMap.put("serialnumber", zhubu.get(x).getSerialnumber());
					zhubuList.add(zhubuMap);
				} else if (zhubu.get(x).getPutTogether() == 2) {// 是竖拼的主布
					Map<String, Object> zhubuMap = Calculate.FixedNPin(zhubu.get(x).getBreadth(), times_fold,
							zhubu.get(0).getSpur(), hem, zhubu.get(0).getInverte(), wide * zhubu.get(x).getPutNumber(),
							high, zhubu.get(x).getBreadthStatus());
					zhubuMap.put("putNumber", zhubu.get(x).getPutNumber());
					zhubuMap.put("putTogether", zhubu.get(x).getPutTogether());
					zhubuMap.put("serialnumber", zhubu.get(x).getSerialnumber());
					zhubuMap.put("serialnumber", zhubu.get(x).getSerialnumber());
					zhubuList.add(zhubuMap);
				}
			}
			double actualWide = 0.0;
			double actualHigh = 0.0;
			boolean hengshu = true;
			boolean shuheng = true;
			for (int a = 0; a < zhubuList.size(); a++) {
				if ((Integer) zhubuList.get(a).get("putTogether") == 1) {
					actualHigh = Arith.add(actualHigh, (Double) zhubuList.get(a).get("actualHigh"));
				} else if ((Integer) zhubuList.get(a).get("putTogether") == 2) {
					if (hengshu) {
						actualHigh = Arith.add(actualHigh, (Double) zhubuList.get(a).get("actualHigh"));
						hengshu = false;
					}
				}
				if (shuheng) {
					if ((Integer) zhubuList.get(a).get("putTogether") == 2) {
						actualWide = Arith.add(actualWide, (Double) zhubuList.get(a).get("actualWide"));
					} else if ((Integer) zhubuList.get(a).get("putTogether") == 1) {
						actualWide = (Double) zhubuList.get(a).get("actualWide");
						shuheng = false;
					}
				}
			}
			map.put("zhubuList", zhubuList);
			List<Map<String, Object>> peibuList = new ArrayList<>();
			Double sumShupin = 0.0;
			for (int x = 0; x < peibu.size(); x++) {
				// 配布是横拼
				if (peibu.get(x).getPutTogether() == 1) {
					Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
							peibu.get(0).getSpur(), 0.0, peibu.get(0).getInverte(), actualWide / production,
							peibu.get(x).getPutNumber() * production, peibu.get(0).getBreadthStatus());
					peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
					peibuList.add(peibuMap);
				} else {// 配布是竖拼
					System.out.println(peibu);
					Map<String, Object> peibuMap = Calculate.FixedNPin(peibu.get(x).getBreadth(), 1.0,
							peibu.get(0).getSpur(), 0.0, peibu.get(0).getInverte(), peibu.get(x).getPutNumber(),
							actualHigh, peibu.get(x).getBreadthStatus());
					System.out.println(peibuMap);
					sumShupin = Arith.add(sumShupin, peibu.get(x).getPutNumber());
					peibuMap.put("serialnumber", peibu.get(x).getSerialnumber());
					peibuList.add(peibuMap);
				}
			}
			for (int e = 0; e < zhubuList.size(); e++) {
				if (zhubu.get(e).getPutTogether() == 2) {
					if ((Integer) zhubuList.get(e).get("putTogether") == 0
							&& (Integer) zhubuList.get(e).get("useInverte") == 0
							|| (Integer) zhubuList.get(e).get("putTogether") == 1
									&& (Integer) zhubuList.get(e).get("useInverte") == 1) {
						zhubuList.get(e).put("clothNumber", Arith.sub((Double) zhubuList.get(e).get("clothNumber"),
								sumShupin * (Double) zhubuList.get(e).get("putNumber")));
						zhubuList.get(e).put("useWide", Arith.sub((Double) zhubuList.get(e).get("clothNumber"),
								sumShupin * (Double) zhubuList.get(e).get("putNumber")));
						zhubuList.get(e).put("actualWide", Arith.sub((Double) zhubuList.get(e).get("clothNumber"),
								sumShupin * (Double) zhubuList.get(e).get("putNumber")));
					}
				}
			}
			map.put("peibuList", peibuList);
		}
		return map;
	}

	
	
	/**
	 * 顾客端价格的计算
	 * @param times_fold
	 * @param hem
	 * @param wide
	 * @param high
	 * @param composition
	 * @return
	 */
	public static Map<String, Object> clientPrice(Double times_fold, Double hem, Double wide, Double high,
			Composition composition) {
		Map<String, Object> map = new HashMap<>();
		Map<String, Object> jieguo = Calculate.FixedNPin(composition.getBreadth(), times_fold, composition.getSpur(),
				hem, composition.getInverte(), wide, high, composition.getBreadthStatus());
		if(jieguo!=null && jieguo.size()!=0){
			map.putAll(jieguo);
			map.put("price", composition.getPrice());
			map.put("serialnumber", composition.getSerialnumber());
			map.put("sumPrice", Arith.mul(composition.getPrice(), (Double) jieguo.get("clothNumber")));
		}
		return map;
	}

	
	
	
	public static void main(String[] args) {
		List<Composition> list = new ArrayList<>();
		Composition c1 = new Composition();
		c1.setBreadth(2.8);
		c1.setSpur(0.0);
		c1.setSerialnumber("主布");
		c1.setBreadthStatus(0);
		c1.setInverte(0);
		c1.setPutTogether(0);
		c1.setPutNumber(0.0);
		c1.setType(1);
		Composition c3 = new Composition();
		c3.setBreadth(2.8);
		c3.setSpur(0.0);
		c3.setSerialnumber("222222");
		c3.setBreadthStatus(0);
		c3.setInverte(0);
		c3.setPutTogether(2);
		c3.setPutNumber(0.5);
		c3.setType(2);
		Composition c2 = new Composition();
		c2.setBreadth(2.8);
		c2.setSpur(0.0);
		c2.setBreadthStatus(0);
		c2.setInverte(0);
		c2.setSerialnumber("33333333333");
		c2.setType(2);
		c2.setPutTogether(1);
		c2.setPutNumber(0.4);
		list.add(c1);
		list.add(c2);
		list.add(c3);
		Map<String, Object> map = Calculate.FixedWidePin(2.0, 0.0, 1.86, 2.61, 2, list);
		System.out.println(map);
	}
}
